package com.limao.Tencent.tenpay.pay;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.http.message.BasicNameValuePair;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.limao.Tencent.tenpay.util.MD5;
import com.limao.Tencent.tenpay.util.MD5Util;
import com.limao.Tencent.tenpay.util.Sha1Util;



public class Tenpay_ask_Provider {
	private static String  packageValue; 
	private static long token_timeStamp;
	private static GetAccessTokenResult accessTokenResult=null;
	
	private String nonceStr;
	private long timeStamp;

	public  String ask(Tenpay_ask_DataClass tenpay)
	{
			//统一下单
			Map<String,String> json =genProductArgs(tenpay);
			nonceStr=genNonceStr();
			timeStamp=genTimeStamp();
			List<BasicNameValuePair> signParams = new LinkedList<BasicNameValuePair>();
	        signParams = new LinkedList<BasicNameValuePair>();
	        signParams.add(new BasicNameValuePair("appid", TenpayConfig.getAPP_ID()));
	        signParams.add(new BasicNameValuePair("noncestr", nonceStr));
	        signParams.add(new BasicNameValuePair("package", "Sign=WXPay"));//+packageValue
	        signParams.add(new BasicNameValuePair("partnerid", TenpayConfig.getMCH_ID()));
	        signParams.add(new BasicNameValuePair("prepayid", (String)json.get("prepay_id")));
	        signParams.add(new BasicNameValuePair("timestamp",String.valueOf(timeStamp)));
	        
	        //signParams.add(new BasicNameValuePair("appkey", TenpayConfig.getAPP_KEY()));

	        
	        String sign = genPackageSign(signParams);
	        
	        
	        Map<String,String> resultMap=new HashMap<String,String>();
	        resultMap.put("sign", sign);
	        

			
	        resultMap.put("appid", TenpayConfig.getAPP_ID());
	        
	        resultMap.put("partnerid", TenpayConfig.getMCH_ID());
	        resultMap.put("prepayid", (String)json.get("prepay_id"));
	        resultMap.put("package", "Sign=WXPay");
	        resultMap.put("noncestr", nonceStr);
	        resultMap.put("timestamp", String.valueOf(timeStamp));
	        resultMap.put("traceId", tenpay.userid);

			
			return JSON.toJSONString(resultMap);
		
	}
	private Map<String,String> genProductArgs( Tenpay_ask_DataClass tenpay) 
	{
		try {
			String traceId =tenpay.userid;// getTraceId(tenpay.out_trade_no);  // traceId 由开发者自定义，可用于订单的查询与跟踪，建议根据支付用户信息生成此id

			timeStamp = genTimeStamp();

			
			nonceStr = genNonceStr();
			
			List<BasicNameValuePair> packageParams = new LinkedList<BasicNameValuePair>();
			packageParams.add(new BasicNameValuePair("appid", TenpayConfig.getAPP_ID()));
			//packageParams.add(new BasicNameValuePair("body", "weixin"));
			packageParams.add(new BasicNameValuePair("body", tenpay.body));
			//packageParams.add(new BasicNameValuePair("input_charset","UTF-8"));
			packageParams.add(new BasicNameValuePair("mch_id", TenpayConfig.getMCH_ID()));
			packageParams.add(new BasicNameValuePair("nonce_str", nonceStr));//nonceStr
			packageParams.add(new BasicNameValuePair("notify_url",tenpay.notify_url));//tenpay.notify_url
			packageParams.add(new BasicNameValuePair("out_trade_no",tenpay.out_trade_no));//tenpay.out_trade_no
			packageParams.add(new BasicNameValuePair("spbill_create_ip","127.0.0.1"));
			packageParams.add(new BasicNameValuePair("total_fee", tenpay.total_fee));//tenpay.total_fee
			//packageParams.add(new BasicNameValuePair("traceId", tenpay.userid));
			packageParams.add(new BasicNameValuePair("trade_type", "APP"));
			
			packageValue = genPackageSign(packageParams);
			packageParams.add(new BasicNameValuePair("sign", packageValue));

			String xmlstring =toXml(packageParams);
			System.out.println("xmlstring:"+xmlstring);

			xmlstring=new String(xmlstring.getBytes("UTF-8"), "ISO-8859-1");
			
			System.out.println("xmlstring2:"+xmlstring);
			
			byte[] buf = Util.httpPost(TenpayConfig.GATEURL,xmlstring);

			
			String content = new String(buf, "UTF-8");
			System.out.println("content:"+content);
			Map<String,String> resultMap=decodeXml(content);


			
	        return resultMap;
			
		} catch (Exception e) {
			System.out.println("genProductArgs fail, ex = " + e.getMessage());
			return null;
		}
		
		
	}
    
	public static Map<String,String> decodeXml(String content) {

		try {
			Map<String, String> xml =XMLParser.getMapFromXML(content);
			 
			
			return xml;
		} catch (Exception e) {
			
		}
		return null;

	}
	
	public String createSHA1Sign(List<BasicNameValuePair> list) {
		StringBuffer sb = new StringBuffer();
		//Set es = list.iterator();
		Iterator it = list.iterator();//es.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			String k = (String) entry.getKey();
			String v = (String) entry.getValue();
			sb.append(k + "=" + v + "&");
		}
		String params = sb.substring(0, sb.lastIndexOf("&"));
		String appsign = Sha1Util.getSha1(params);
		System.out.println("sha1 sb:" + params);
		System.out.println("app sign:" + appsign);
		return appsign;
	}
	private String genSign(List<BasicNameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		
		int i = 0;
		for (; i < params.size() - 1; i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append(params.get(i).getName());
		sb.append('=');
		sb.append(params.get(i).getValue());
		
        sb.append("sign str\n"+sb.toString()+"\n\n");
		String appSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();

		System.out.println("genSign, appSign = " + appSign);
		return appSign;
		
	
	}
	private long genTimeStamp() {
		return System.currentTimeMillis() / 1000;
	}
	private String genNonceStr() {
		Random random = new Random();
		return MD5Util.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
	}
	
	/**
	 生成签名
	 */

	private String genPackageSign(List<BasicNameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		
		for (int i = 0; i < params.size(); i++) {
			sb.append(params.get(i).getName());
			sb.append('=');
			sb.append(params.get(i).getValue());
			sb.append('&');
		}
		sb.append("key=");
		sb.append(TenpayConfig.getAPP_KEY());
		

		
		
		
		//String packageSign = MD5Util.getMessageDigest(sb.toString().getBytes()).toUpperCase();
		String packageSign = MD5Util.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
//		Log.e("orion",packageSign);
		return packageSign;
	}
	
	private String toXml(List<BasicNameValuePair> params) {
		StringBuilder sb = new StringBuilder();
		sb.append("<xml>");
		for (int i = 0; i < params.size(); i++) {
			sb.append("<"+params.get(i).getName()+">");


			sb.append(params.get(i).getValue());
			sb.append("</"+params.get(i).getName()+">");
		}
		sb.append("</xml>");

//		Log.e("orion",sb.toString());
		return sb.toString();
	}
	

	protected GetAccessTokenResult  getAccessToken() {
		
		long time=new Date().getTime();
		if (accessTokenResult!=null&&time<token_timeStamp+3600000)
		{
			return accessTokenResult;
		}
		token_timeStamp=time;

		GetAccessTokenResult result = new GetAccessTokenResult();

		String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
				TenpayConfig.getAPP_ID(), TenpayConfig.getMCH_ID());
		
		byte[] buf = Util.httpGet(url);
		if (buf == null || buf.length == 0) {
			result.localRetCode = LocalRetCode.ERR_HTTP;
			return result;
		}
		String content = new String(buf);
		result.parseFrom(content);
		accessTokenResult=result;
		return result;
	}
	//---------------------
	private class GetAccessTokenResult {
		
		private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetAccessTokenResult";
		
		public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER;
		public String accessToken;
		public int expiresIn;
		public int errCode;
		public String errMsg;
		
		public void parseFrom(String content) {

			if (content == null || content.length() <= 0) {
				localRetCode = LocalRetCode.ERR_JSON;
				return;
			}
			
			try {
				JSONObject json = JSON.parseObject(content);
				if (json.containsKey("access_token")) { // success case
					accessToken = json.getString("access_token");
					expiresIn = json.getIntValue("expires_in");
					localRetCode = LocalRetCode.ERR_OK;
				} else {
					errCode = json.getIntValue("errcode");
					errMsg = json.getString("errmsg");
					localRetCode = LocalRetCode.ERR_JSON;
				}
				
			} catch (Exception e) {
				localRetCode = LocalRetCode.ERR_JSON;
			}
		}

	}
	private static enum LocalRetCode {
		ERR_OK, ERR_HTTP, ERR_JSON, ERR_OTHER
	}
	
	private static class GetPrepayIdResult {
		
		private static final String TAG = "MicroMsg.SDKSample.PayActivity.GetPrepayIdResult";
		
		public LocalRetCode localRetCode = LocalRetCode.ERR_OTHER;
		public String prepayId;
		public int errCode;
		public String errMsg;
		
		public void parseFrom(String content) {
			
			if (content == null || content.length() <= 0) {
				//Log.e(TAG, "parseFrom fail, content is null");
				localRetCode = LocalRetCode.ERR_JSON;
				return;
			}
			
			try {
				JSONObject json =JSON.parseObject(content);
				if (json.containsKey("prepayid")) { // success case
					prepayId = json.getString("prepayid");
					localRetCode = LocalRetCode.ERR_OK;
				} else {
					localRetCode = LocalRetCode.ERR_JSON;
				}
				
				errCode = json.getIntValue("errcode");
				errMsg = json.getString("errmsg");
				
			} catch (Exception e) {
				localRetCode = LocalRetCode.ERR_JSON;
			}
		}
	}
}
